package com.xhtt.modules.task.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhtt.common.exception.RRException;
import com.xhtt.common.utils.CopyUtils;
import com.xhtt.common.utils.PageUtils;
import com.xhtt.common.utils.Query;
import com.xhtt.common.utils.RestResult;
import com.xhtt.modules.cfg.service.CfgHoseInfoService;
import com.xhtt.modules.cfg.service.CfgPumpInfoService;
import com.xhtt.modules.cfg.service.CfgTubeInfoService;
import com.xhtt.modules.msg.entity.MsgInfo;
import com.xhtt.modules.msg.entity.RestMsgFailLog;
import com.xhtt.modules.msg.service.MsgInfoService;
import com.xhtt.modules.msg.service.MsgUserService;
import com.xhtt.modules.msg.service.RestMsgFailLogService;
import com.xhtt.modules.sys.entity.SysUserEntity;
import com.xhtt.modules.sys.service.SysUserService;
import com.xhtt.modules.task.dao.TaskShipTaskMapper;
import com.xhtt.modules.task.entity.*;
import com.xhtt.modules.task.model.Confirm1Model;
import com.xhtt.modules.task.model.ConnectTaskDetail;
import com.xhtt.modules.task.model.TaskOperConnectModel;
import com.xhtt.modules.task.model.TaskOperModel;
import com.xhtt.modules.task.model.lmtask.BusinessCheckModel;
import com.xhtt.modules.task.model.lmtask.TaskOperLMModel;
import com.xhtt.modules.task.model.msg.PlanTaskModel;
import com.xhtt.modules.task.model.oper.TaskOperDCQYModel;
import com.xhtt.modules.task.model.ship.ArrangeModel;
import com.xhtt.modules.task.model.ship.TaskOperCCRModel;
import com.xhtt.modules.task.model.ship.TaskOperOtherModel;
import com.xhtt.modules.task.model.ship.WorkUserModel;
import com.xhtt.modules.task.schedule.TaskDetailSchedule;
import com.xhtt.modules.task.service.*;
import com.xhtt.modules.task.utils.RestUtils;
import com.xhtt.modules.task.utils.StaticUtils;
import com.xhtt.modules.task.utils.TaskUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 船分支任务 服务实现类
 * </p>
 *
 * @author feipc
 * @since 2019-02-27
 */
@Service
public class TaskShipTaskServiceImpl extends ServiceImpl<TaskShipTaskMapper, TaskShipTask> implements TaskShipTaskService {

    @Autowired
    private TaskShipTaskProdStepService taskShipTaskProdStepService;
    @Autowired
    private TaskShipPlanService taskShipPlanService;
    @Autowired
    private TaskDetailSchedule taskDetailSchedule;
    @Autowired
    private TaskUtils taskUtils;
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private TaskShipTaskLmService lmService;
    @Autowired
    private TaskShipTaskLmProductCompanyService lmProductCompanyService;
    @Resource
    private TaskStepService taskStepService;
    @Autowired
    private MsgInfoService msgInfoService;
    @Autowired
    private MsgUserService msgUserService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private CfgTubeInfoService cfgTubeInfoService;
    @Autowired
    private CfgPumpInfoService cfgPumpInfoService;
    @Autowired
    private CfgHoseInfoService cfgHoseInfoService;
    @Autowired
    private TaskShipPlanProductService shipPlanProductService;
    @Autowired
    private RestMsgFailLogService restMsgFailLogService;
    @Autowired
    private RestUtils restUtils;


    @Override
    public ArrangeModel getTaskDetail(Integer planId, SysUserEntity user) {
        ArrangeModel sm = new ArrangeModel();
        TaskShipPlan shipPlan = taskShipPlanService.getById(planId);
        if (null == shipPlan) {
            throw new RRException("对象不存在");
        }
        sm.setPlanId(planId);
        sm.setMainTaskName(shipPlan.getTaskName());
        List<TaskShipTask> taskList = this.list(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getShipPlanId, planId));

        if (shipPlan.getStatus().intValue() == 2)//如果在待分配状态下，就只能看自己组的任务数据
        {
            if (null == user.getTeamId()) {
                taskList.clear();
            } else {
                //过滤下任务列表
                taskList.removeIf(t -> (null == t.getExecTeamId() || t.getExecTeamId().intValue() != user.getTeamId().intValue()));
            }
        }

        //找到排管任务再处理
        for (TaskShipTask task : taskList) {
            if (null == task.getIfPhoto()) {
                if (task.getType().intValue() == 5) {//打尺取样要默认是
                    task.setIfPhoto(1);
                } else {
                    task.setIfPhoto(0);//默认设置0
                }
            }
            if (null == task.getIfConfirm()) {
                task.setIfConfirm(0);//默认设置0
            }
            //找排管步骤
            if (task.getType().intValue() == 1) {
                //再找连接步骤
                List<TaskShipTaskProdStep> taskProdSteps = taskShipTaskProdStepService.list(new LambdaQueryWrapper<TaskShipTaskProdStep>().eq(TaskShipTaskProdStep::getShipTaskId, task.getId()).orderByAsc(TaskShipTaskProdStep::getStep));

                task.setTaskProdSteps(taskProdSteps);
                task.setProductId(taskProdSteps.get(0).getProductId());
                task.setProductName(taskProdSteps.get(0).getProductName());
            }
            if (task.getType().intValue() == 5)//打尺取样
            {
                TaskShipPlanProduct pp = shipPlanProductService.getOne(new LambdaQueryWrapper<TaskShipPlanProduct>().eq(TaskShipPlanProduct::getId, task.getPlanProductId())
                        .select(TaskShipPlanProduct::getId, TaskShipPlanProduct::getProductName, TaskShipPlanProduct::getPotName));
                if (null != pp) {
                    task.setProductName(pp.getProductName());
                    task.setPotName(pp.getPotName());
                }
            }
            taskDetailSchedule.getTaskDetail(task);

        }
        sm.setTasks(taskList);

        return sm;
    }

    @Override
    @Transactional
    public void pubTask(List<TaskShipTask> tasks, SysUserEntity user) {
        List<TaskShipTask> dbs = new ArrayList<>();
        TaskShipTask db;
        Integer planId = 0;
        List<Integer> thisIds = new ArrayList<>();//
        for (TaskShipTask taskShipTask : tasks) {
            thisIds.add(taskShipTask.getId());
            if (CollectionUtils.isNotEmpty(taskShipTask.getUserAssistModel())) {
                taskShipTask.setUserAssist(JSON.toJSONString(taskShipTask.getUserAssistModel()));
            } else {
                taskShipTask.setUserAssist(JSON.toJSONString(Collections.EMPTY_LIST));
            }
            if (taskShipTask.getType().intValue() == 1) {
                taskShipTask.setIfConfirm(1);//管线任务默认要确认
            }
            db = this.getById(taskShipTask.getId());
            CopyUtils.copyProperties(taskShipTask, db);
            db.setStatus(4);//4进行中9完成(跟主任务同步)
            db.setPubTime(LocalDateTime.now());
            //判断下是不是有确认人，因为除了管线任务会手动设置 其他任务要默认选某组的组长（选了需要确认的话）
            if (null == db.getConfirm1User() && db.getIfConfirm().intValue() == 1) {
                db.setConfirm1User(user.getUserId().intValue());
                db.setConfirm1UserName(user.getName());

                db.setConfirm2User(user.getUserId().intValue());//省得烦，直接设置成一样的
                db.setConfirm2UserName(user.getName());
            }

            //判断有没有任务频率,也就ccr任务会有了 fuck
            if (StringUtils.isNotEmpty(db.getTaskFre())) {
                int count = StaticUtils.gettaskCount(db.getTaskFre(), db.getTaskStartDate(), db.getTaskEndDate());
                db.setCcrTotal(count);
                db.setCcrDone(0);
            }
            dbs.add(db);
            planId = db.getShipPlanId();
        }
        this.updateBatchById(dbs);

        //把软管保存放在分配里面了
        for (TaskShipTask hoseTask : tasks) {
            if (1 == hoseTask.getType().intValue()) {
                List<TaskShipTaskProdStep> planProductList = hoseTask.getTaskProdSteps();//获取输送产品+管线步骤  注意web要在每一步都设置productid和name
                taskExecutor.submit(() -> taskStepService.synchronizeFunc(planProductList, hoseTask.getId(), planProductList.get(0).getProductId(), planProductList.get(0).getProductName(), user));
            }
        }


        //如果这个主任务的所有子任务都被分配完了 那就更新主任务状态为4
        int count = this.count(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getShipPlanId, planId).
                and(qw -> qw.eq(TaskShipTask::getStatus, 0).or(qw2 -> qw2.eq(TaskShipTask::getStatus, 2)))
                .notIn(TaskShipTask::getId, thisIds));
        if (count == 0) {
            TaskShipPlan plan = new TaskShipPlan();
            plan.setId(planId);
            plan.setStatus(4);
            taskShipPlanService.updateById(plan);
        }

        //发消息
        taskExecutor.submit(() -> {
            List<MsgInfo> msgList = new ArrayList<>();
            for (TaskShipTask tk : dbs) {
                String productName = "";
                if (tk.getType().intValue() == 1)//管线任务 获取产品
                {
                    productName = tk.getTaskProdSteps().get(0).getProductName();
                }
                PlanTaskModel ptm = new PlanTaskModel(tk.getId(), tk.getMainTaskName(), tk.getName(), productName, tk.getTaskStartDate(), tk.getUserAssistModel());
                MsgInfo msg = new MsgInfo("计划任务", tk.getMainTaskName(), "任务待完成提交", JSON.toJSONString(ptm));
                Set<Integer> userIds = new HashSet<>();
                userIds.add(tk.getUserMainId());
                msg.setUserIdList(userIds);
                msgList.add(msg);
            }
            msgInfoService.saveMsgBatch(msgList);
        });
    }

    @Override
    public PageUtils confirmTaskList(Map<String, Object> params) {
        Page<TaskShipTask> page = new Query<TaskShipTask>(params).getPage();
        page.setRecords(baseMapper.confirmTaskList(page, params));
        return new PageUtils(page);
    }

    @Override
    public TaskOperModel taskOperDetail(Integer taskId, Integer userId) {
        TaskShipTask task = this.getOne(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getId, taskId).select(TaskShipTask::getShipPlanId, TaskShipTask::getType,
                TaskShipTask::getConfirm1Reason, TaskShipTask::getConfirm1Status, TaskShipTask::getConfirm2Reason, TaskShipTask::getConfirm2Status, TaskShipTask::getCcrDone, TaskShipTask::getOperDetail,
                TaskShipTask::getPlanProductId, TaskShipTask::getConfirm1User, TaskShipTask::getConfirm2User));
        if (null == task) {
            throw new RRException("无数据");
        }
        String operDetail = task.getOperDetail();
        if (StringUtils.isEmpty(operDetail)) {
            if (1 == task.getType().intValue()) {//排管任务
                //根据产品id获取这个产品的连接管道 组
                List<TaskShipTaskProdStep> steps = taskShipTaskProdStepService.list(new LambdaQueryWrapper<TaskShipTaskProdStep>().eq(TaskShipTaskProdStep::getShipTaskId, taskId).orderByAsc(TaskShipTaskProdStep::getStep));
                //转换成model里面的steps
                List<ConnectTaskDetail> connectTaskDetails = new ArrayList<>();
                steps.forEach(p -> {
                    ConnectTaskDetail connectTaskDetail = new ConnectTaskDetail();
                    connectTaskDetail.setPointName(p.getTypeName());
                    String rfid = taskUtils.getRfid(null == p.getType() ? 0 : p.getType().intValue(), null == p.getTypeId() ? 0 : p.getTypeId().intValue());
                    if (p.getType().intValue() == 4) {
                        connectTaskDetail.setStatus(-1);//泊位不用扫描，
                    }
                    if (StringUtils.isEmpty(rfid)) {
                        connectTaskDetail.setStatus(1);//为空默认已经扫描，
                    }

                    connectTaskDetail.setRfid(rfid);
                    connectTaskDetails.add(connectTaskDetail);
                });

                TaskOperConnectModel connectModel = new TaskOperConnectModel();//详情对象
                connectModel.setTaskId(taskId);
                connectModel.setProductName(steps.get(0).getProductName());
                connectModel.setConnectTaskDetailList(connectTaskDetails);
                if (null != task.getConfirm1User() && userId.intValue() == task.getConfirm1User().intValue()) {
                    connectModel.setWhichConfirmUser(1);
                } else if (null != task.getConfirm2User() && userId.intValue() == task.getConfirm2User().intValue()) {
                    connectModel.setWhichConfirmUser(2);
                }
                //这里提前构造好确认人1的确认详情对象
                connectModel.setConfirm1Model(new Confirm1Model(connectTaskDetails, null, null));
                return connectModel;
            } else if (2 == task.getType().intValue()) {//LM任务
                TaskOperLMModel lmModel = new TaskOperLMModel();
                //假数据
//                List<ProductModel> pl = new ArrayList<>();
//                BusinessCheckModel bb = new BusinessCheckModel("1111",LocalDateTime.now(),LocalDateTime.now(),LocalDateTime.now(),LocalDateTime.now());
//                List<BusinessCheckModel> bs = new ArrayList<>();
//                bs.add(bb);
//                ProductModel p = new ProductModel("4356456",LocalDateTime.now(),LocalDateTime.now(),LocalDateTime.now(),LocalDateTime.now(),LocalDateTime.now(),LocalDateTime.now(),LocalDateTime.now(),bs);
//                pl.add(p);pl.add(p);
//                lmModel.setProductModelList(pl);
                lmModel.setTaskId(taskId);
                return lmModel;
            } else if (5 == task.getType().intValue()) {//打尺取样任务
                TaskOperDCQYModel dcqyModel = new TaskOperDCQYModel();
                TaskShipPlanProduct pp = shipPlanProductService.getOne(new LambdaQueryWrapper<TaskShipPlanProduct>().eq(TaskShipPlanProduct::getId, task.getPlanProductId()).select(TaskShipPlanProduct::getId, TaskShipPlanProduct::getProductName, TaskShipPlanProduct::getPotName));
                if (null != pp) {
                    dcqyModel.setProductName(pp.getProductName());
                    dcqyModel.setPotName(pp.getPotName());
                }
                dcqyModel.setTaskId(taskId);
                return dcqyModel;
            } else if (3 == task.getType().intValue() || 5 < task.getType().intValue()) {//其他任务？
                TaskOperOtherModel model = new TaskOperOtherModel();
                model.setTaskId(taskId);

                if (null != task.getUserMainId()) {
                    model.setUserMain(sysUserService.getOne(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUserId, task.getUserMainId())).getName());
                }
                String userAssist = task.getUserAssist();
                if (StringUtils.isNotEmpty(userAssist)) {
                    List<WorkUserModel> us = JSON.parseArray(userAssist, WorkUserModel.class);
                    List<String> ss = us.stream().map(workUserModel -> workUserModel.getName()).collect(Collectors.toList());
                    model.setUserAssist(String.join(",", ss));
                }
                model.setTaskRequire(task.getTaskRequire());
                return model;
            } else if (4 == task.getType().intValue()) {//CCR
                TaskOperCCRModel model = new TaskOperCCRModel();
                model.setTaskId(taskId);
//                model.setUserMain(sysUserService.getOne(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUserId,task.getUserMainId())).getName());
//                String userAssist = task.getUserAssist();
//                if(StringUtils.isNotEmpty(userAssist))
//                {
//                    List<WorkUserModel> us = JSON.parseArray(userAssist,WorkUserModel.class);
//                    List<String> ss = us.stream().map(workUserModel -> workUserModel.getName()).collect(Collectors.toList());
//                    model.setUserAssist(String.join(",",ss));
//                }
//                model.setTaskRequire(task.getTaskRequire());
                return model;
            }
        } else {
            if (1 == task.getType().intValue()) {
                TaskOperConnectModel connectModel = JSON.parseObject(operDetail, TaskOperConnectModel.class);
//                if (null != task.getConfirm1User()) {
//                    if (userId.intValue() == task.getConfirm1User().intValue()) {
                connectModel.setConfirm1Reason(task.getConfirm1Reason());
                connectModel.setConfirm1Result(task.getConfirm1Status());
//                    } else {
                connectModel.setConfirmResult(task.getConfirm2Status());
                connectModel.setConfirmReason(task.getConfirm2Reason());
//                    }
//                }
                if (null != task.getConfirm1User() && userId.intValue() == task.getConfirm1User().intValue()) {
                    connectModel.setWhichConfirmUser(1);
                } else if (null != task.getConfirm2User() && userId.intValue() == task.getConfirm2User().intValue()) {
                    connectModel.setWhichConfirmUser(2);
                }
                return connectModel;
            } else if (2 == task.getType().intValue()) {
                TaskOperLMModel lmModel = JSON.parseObject(operDetail, TaskOperLMModel.class);
                lmModel.setConfirmResult(task.getConfirm2Status());
                lmModel.setConfirmReason(task.getConfirm2Reason());
                return lmModel;
            } else if (5 == task.getType().intValue()) {
                TaskOperDCQYModel dcqyModel = JSON.parseObject(operDetail, TaskOperDCQYModel.class);
                dcqyModel.setConfirmReason(task.getConfirm2Reason());
                dcqyModel.setConfirmResult(task.getConfirm2Status());
                return dcqyModel;
            } else if (3 == task.getType().intValue() || 5 < task.getType().intValue()) {
                TaskOperOtherModel otherModel = JSON.parseObject(operDetail, TaskOperOtherModel.class);
                otherModel.setConfirmReason(task.getConfirm2Reason());
                otherModel.setConfirmResult(task.getConfirm2Status());
                return otherModel;
            } else if (4 == task.getType().intValue()) {
                //这个接口app调用 获取ccr任务详情，只获取当前操作的这次ccr记录
                List<TaskOperCCRModel> ccrModelList = JSON.parseArray(operDetail, TaskOperCCRModel.class);
                ccrModelList.forEach(taskOperCCRModel -> {
                    taskOperCCRModel.setConfirmReason(task.getConfirm2Reason());
                    taskOperCCRModel.setConfirmResult(task.getConfirm2Status());
                });
                int done = task.getCcrDone();
                int nowTime = done + 1;//本次操作次数
                if (ccrModelList.size() == nowTime)//说明之前临时保存过了，就直接取
                {
                    return ccrModelList.get(nowTime - 1);
                } else {
                    TaskOperCCRModel model = new TaskOperCCRModel();
                    model.setTaskId(taskId);
                    return model;
                }
            }
        }


        return null;
    }

    @Override
    public void tempSave(TaskOperModel model) {
        TaskShipTask task = this.getById(model.getTaskId());
        if (null == task) {
            throw new RRException("对象不存在");
        }
        checkTask(task, model);
//        task.setPubTime(LocalDateTime.now());为什么会设置分配时间呢？？？我也不知道了，但是说不通啊，所以就注释了
        this.updateById(task);
    }

    @Data
    @AllArgsConstructor
    public class Lm implements Runnable {
        private TaskShipTask task;
        private TaskOperModel model;

        @Override
        public void run() {
            //全删全增
            List<TaskShipTaskLm> lms = lmService.list(new LambdaQueryWrapper<TaskShipTaskLm>().eq(TaskShipTaskLm::getTaskShipTaskId, task.getId()));
            if (CollectionUtils.isNotEmpty(lms)) {
                List<Integer> lmIds = lms.stream().map(l -> l.getId()).collect(Collectors.toList());
                lmProductCompanyService.remove(new LambdaQueryWrapper<TaskShipTaskLmProductCompany>().in(TaskShipTaskLmProductCompany::getLmId, lmIds));
                lmService.removeByIds(lmIds);
            }
            TaskOperLMModel lmModel = new TaskOperLMModel();
            CopyUtils.copyProperties(model, lmModel);

            TaskShipTaskLm lm = new TaskShipTaskLm();
            CopyUtils.copyProperties(lmModel, lm);
            lm.setTaskShipTaskId(task.getId());
            lmService.save(lm);
            Integer lmId = lm.getId();

            List<BusinessCheckModel> businessCheckModelList = lmModel.getBusinessCheckModelList();
            //第二级
            if (CollectionUtils.isNotEmpty(businessCheckModelList)) {
                List<TaskShipTaskLmProductCompany> pms = new ArrayList<>();
                TaskShipTaskLmProductCompany pm;
                for (BusinessCheckModel b : businessCheckModelList) {
                    pm = new TaskShipTaskLmProductCompany();
                    CopyUtils.copyProperties(b, pm);
                    pm.setLmId(lmId);
                    pms.add(pm);
                }
                lmProductCompanyService.saveBatch(pms);
            }
        }
    }

    @Override
    @Transactional
    public void submitTask(TaskOperModel model) {
        TaskShipTask task = this.getById(model.getTaskId());
        if (null == task) {
            throw new RRException("对象不存在");
        }
        boolean skipConfirm = null == model.getSkipConfirm() ? false : model.getSkipConfirm();//是否直接不用干活直接提交
        if (!skipConfirm) {
            checkTask(task, model);
            //ccr任务要判断操的次数
            if (task.getType().intValue() == 4)//CCR
            {
                //设置本次的完成时间-取出最后一条更新一下时间就好了
                List<TaskOperCCRModel> ccrList = JSON.parseArray(task.getOperDetail(), TaskOperCCRModel.class);
                int size = ccrList.size();
                com.xhtt.modules.task.model.ship.TaskOperCCRModel lastCCR = ccrList.get(size - 1);
                lastCCR.setFinishTime(LocalDateTime.now());
                task.setOperDetail(JSON.toJSONString(ccrList));

                int total = task.getCcrTotal();
                int done = task.getCcrDone() + 1;
                task.setCcrDone(done);
                if (total != done)//说明这次ccr没做完
                {
                    this.updateById(task);
                    return;
                }
            }
            if (task.getType().intValue() == 2)//LM任务保存详情
            {
                taskExecutor.submit(new Lm(task, model));//保存狗日的LM详情
            }
        }
        task.setFinishTime(LocalDateTime.now());//完成时间设置
        task.setStatus(9);//状态设置

        //判断是否要确认，不要的话直接把确认状态改成1了,状态改成10 已确认
        if (task.getIfConfirm() == 0) {
            task.setConfirm1Status(1);
            task.setConfirm2Status(1);
            task.setStatus(10);
        }
        this.updateById(task);
        //判断是否所有子任务都做完了，是的话就更新主任务的状态为9,然后还要找到管线任务，把管线们设置成未使用
        int count = this.count(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getShipPlanId, task.getShipPlanId()).ne(TaskShipTask::getId, task.getId()).lt(TaskShipTask::getStatus, 9));
        if (count == 0) {
            Integer planId = task.getShipPlanId();
            TaskShipPlan p = new TaskShipPlan();
            p.setStatus(9);
            p.setId(planId);
            //如果自己是不用确认的，那就判断是否所有子任务都确认完了，是的话就更新主任务的状态为10
            if (task.getIfConfirm() == 0) {
                int countC = this.count(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getShipPlanId, task.getShipPlanId()).ne(TaskShipTask::getId, task.getId()).lt(TaskShipTask::getStatus, 10));
                if (countC == 0) {
                    p.setStatus(10);
                }
            }
            taskShipPlanService.updateById(p);

            //找到管线任务，把管线们设置成未使用
            List<TaskShipTask> connectTaskList = this.list(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getShipPlanId, planId).eq(TaskShipTask::getType, 1).select(TaskShipTask::getId));
            if (CollectionUtils.isNotEmpty(connectTaskList)) {
                List<Integer> connectTaskIds = connectTaskList.stream().map(taskShipTask -> taskShipTask.getId()).collect(Collectors.toList());
                //获取节点
                List<TaskShipTaskProdStep> steps = taskShipTaskProdStepService.list(new LambdaQueryWrapper<TaskShipTaskProdStep>().in(TaskShipTaskProdStep::getShipTaskId, connectTaskIds).in(TaskShipTaskProdStep::getType, Arrays.asList(new Integer[]{2, 3, 5})));
                //设置为未使用
                List<Integer> upTubeIds = new ArrayList<>();
                List<Integer> upPumpIds = new ArrayList<>();
                List<Integer> upHoseIds = new ArrayList<>();
                for (TaskShipTaskProdStep step : steps) {
                    if (step.getType().intValue() == 2) {
                        upTubeIds.add(step.getTypeId());
                    } else if (step.getType().intValue() == 3) {
                        upPumpIds.add(step.getTypeId());
                    } else if (step.getType().intValue() == 5) {
                        upHoseIds.add(step.getTypeId());
                    }
                }
                if (CollectionUtils.isNotEmpty(upTubeIds)) {
                    cfgTubeInfoService.updateUnUsed(upTubeIds);
                }
                if (CollectionUtils.isNotEmpty(upPumpIds)) {
                    cfgPumpInfoService.updateUnUsed(upPumpIds);
                }
                if (CollectionUtils.isNotEmpty(upHoseIds)) {
                    cfgHoseInfoService.updateUnUsed(upHoseIds);
                }

            }
        }

        //发消息
        taskExecutor.submit(() -> {
            if (task.getIfConfirm() == 1) {
                String productName = "";
                if (task.getType().intValue() == 1)//管线任务 获取产品
                {
                    TaskShipTaskProdStep step = taskShipTaskProdStepService.getOne(new LambdaQueryWrapper<TaskShipTaskProdStep>().eq(TaskShipTaskProdStep::getShipTaskId, task.getId()).select(TaskShipTaskProdStep::getId, TaskShipTaskProdStep::getProductName));
                    productName = step.getProductName();
                }
                PlanTaskModel ptm = new PlanTaskModel(task.getId(), task.getMainTaskName(), task.getName(), productName, task.getTaskStartDate(), task.getUserAssistModel());
                TaskShipPlan plan = taskShipPlanService.getOne(new LambdaQueryWrapper<TaskShipPlan>().eq(TaskShipPlan::getId, task.getShipPlanId()).select(TaskShipPlan::getId, TaskShipPlan::getTaskName));
                MsgInfo msg = new MsgInfo("计划任务", plan.getTaskName(), "任务待确认", JSON.toJSONString(ptm));

                //一个人确认？2个人确认？
                List<Integer> userIds = new ArrayList<>();
                if (task.getType().intValue() == 1)//管线任务 2人确认
                {
                    userIds.add(task.getConfirm1User());
                } else {
                    userIds.add(task.getConfirm2User());
                }
//                msg.setUserIdList(userIds);
                msgUserService.insertBatch(msg, userIds);
            }
        });

    }

    @Override
    @Transactional
    public void commitTask(TaskOperModel model, Integer userId) {
        TaskShipTask task = this.getById(model.getTaskId());
        if (task.getIfConfirm().intValue() == 1) {
            if (task.getConfirm1User().equals(userId) && null == task.getConfirm1Status()) {
                task.setConfirm1Status(model.getConfirmResult());
                task.setConfirm1Reason(model.getConfirmReason());
            }
            if (task.getConfirm2User().equals(userId) && null == task.getConfirm2Status()) {
                task.setConfirm2Status(model.getConfirmResult());
                task.setConfirm2Reason(model.getConfirmReason());
                task.setStatus(10);//确认完成
                //判断是不是子任务都确认完了( 除了自己以外，没有状态小于9的数据了)，是的话把主任务状态也改一下
                Integer shipPlanId = task.getShipPlanId();
                int count = this.count(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getShipPlanId, shipPlanId).lt(TaskShipTask::getStatus, 10).ne(TaskShipTask::getId, task.getId()));
                if (0 == count) {
                    TaskShipPlan plan = new TaskShipPlan();
                    plan.setId(shipPlanId);
                    plan.setStatus(10);
                    taskShipPlanService.updateById(plan);
                }
            }
            if (task.getType().intValue() == 1 && null == task.getConfirm2Status())//如果是管线连接任务，并且发现第二个人还没确认 ，那就给第二个人发消息，
            {
                //保存确认详情
                TaskOperConnectModel cm = JSON.parseObject(task.getOperDetail(), TaskOperConnectModel.class);
                CopyUtils.copyProperties(model, cm);
                task.setOperDetail(JSON.toJSONString(cm));
                //发消息
                taskExecutor.submit(() -> {
                    if (task.getIfConfirm() == 1) {
                        String productName = "";
                        if (task.getType().intValue() == 1)//管线任务 获取产品
                        {
                            TaskShipTaskProdStep step = taskShipTaskProdStepService.getOne(new LambdaQueryWrapper<TaskShipTaskProdStep>().eq(TaskShipTaskProdStep::getShipTaskId, task.getId()).select(TaskShipTaskProdStep::getId, TaskShipTaskProdStep::getProductName));
                            productName = step.getProductName();
                        }
                        PlanTaskModel ptm = new PlanTaskModel(task.getId(), task.getMainTaskName(), task.getName(), productName, task.getTaskStartDate(), task.getUserAssistModel());
                        TaskShipPlan plan = taskShipPlanService.getOne(new LambdaQueryWrapper<TaskShipPlan>().eq(TaskShipPlan::getId, task.getShipPlanId()).select(TaskShipPlan::getId, TaskShipPlan::getTaskName));
                        MsgInfo msg = new MsgInfo("计划任务", plan.getTaskName(), "任务待确认", JSON.toJSONString(ptm));

                        List<Integer> userIds = new ArrayList<>();
                        userIds.add(task.getConfirm2User());
//                        msg.setUserIdList(userIds);
                        msgUserService.insertBatch(msg, userIds);
                    }
                });
            }

        }
        this.updateById(task);
    }

    @Override
    public List<TaskShipTask> shiftsList(Integer selfId) {
        return baseMapper.shiftsList(selfId);
    }

    @Override
    public List<TaskOperCCRModel> taskCCRDetail(Integer taskId, Integer userId) {
        TaskShipTask task = this.getOne(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getId, taskId).select(TaskShipTask::getId, TaskShipTask::getOperDetail,
                TaskShipTask::getConfirm1Status, TaskShipTask::getConfirm1Reason, TaskShipTask::getConfirm2Status, TaskShipTask::getConfirm2Reason));
        if (null == task) {
            throw new RRException("对象不存在");
        }
        String detail = task.getOperDetail();
        if (StringUtils.isEmpty(detail)) {
            return Collections.EMPTY_LIST;
        } else {
            List<TaskOperCCRModel> list = JSON.parseArray(detail, TaskOperCCRModel.class);
            list.forEach(taskOperCCRModel -> {
//                if (null != task.getConfirm1User()) {
//                    if (userId.intValue() == task.getConfirm1User().intValue()) {
                taskOperCCRModel.setConfirmResult(task.getConfirm1Status());
                taskOperCCRModel.setConfirmReason(task.getConfirm1Reason());
//                    } else {
//                        taskOperCCRModel.setConfirmResult(task.getConfirm2Status());
//                        taskOperCCRModel.setConfirmReason(task.getConfirm2Reason());
//                    }
//                }
            });
            return list;
        }
    }

    @Override
    public String taskCCRStatus(Integer taskId) {
        TaskShipTask task = this.getOne(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getId, taskId).select(TaskShipTask::getCcrDone, TaskShipTask::getOperDetail));
        if (null == task) {
            throw new RRException("对象不存在");
        }
        int done = task.getCcrDone();
        String detail = task.getOperDetail();
        if (StringUtils.isEmpty(detail)) {
            return "未开始";
        }
        int nowTime = done + 1;//本次的次数
        List<TaskOperCCRModel> modelList = JSON.parseArray(detail, TaskOperCCRModel.class);
        if (modelList.size() < nowTime) {
            return "未开始";
        } else {
            return "进行中";
        }
    }

    @Override
    public List<String> getTaskProduct(Integer taskId) {
        TaskShipTask task = this.getOne(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getId, taskId).select(TaskShipTask::getShipPlanId));
        if (null == task) {
            throw new RRException("对象不存在");
        }
        List<String> products = new ArrayList<>();
        List<TaskShipPlanProduct> list = shipPlanProductService.list(new LambdaQueryWrapper<TaskShipPlanProduct>().eq(TaskShipPlanProduct::getShipPlanId, task.getShipPlanId())
                .select(TaskShipPlanProduct::getId, TaskShipPlanProduct::getProductName));
        if (CollectionUtils.isNotEmpty(list)) {
            products.addAll(list.stream().map(pp -> pp.getProductName()).collect(Collectors.toList()));
        }
        return products;
    }

    @Override
    public void start(Integer taskId) {
        TaskShipTask task = this.getOne(new LambdaQueryWrapper<TaskShipTask>().eq(TaskShipTask::getId, taskId).select(TaskShipTask::getId, TaskShipTask::getType, TaskShipTask::getOperDetail, TaskShipTask::getStartTime));
        if (null == task) {
            throw new RRException("对象不存在");
        }
        task.setStartTime(LocalDateTime.now());
        if (task.getType().intValue() == 4)//如果是ccr任务 他妈的还要特殊处理，真的是日了🐶了
        {
            TaskOperCCRModel ccr = new TaskOperCCRModel();
            ccr.setStartTime(LocalDateTime.now());
            String detail = task.getOperDetail();
            List<TaskOperCCRModel> ccrList;
            if (StringUtils.isNotEmpty(detail)) {
                ccrList = JSON.parseArray(detail, TaskOperCCRModel.class);
                ccrList.add(ccr);
            } else {
                ccrList = new ArrayList<>();
                ccrList.add(ccr);
            }
            task.setOperDetail(JSON.toJSONString(ccrList));
        }
        this.updateById(task);
    }

    private void checkTask(TaskShipTask task, TaskOperModel model) {
        //判断下类型吧
        int type = task.getType().intValue();
        if (1 == type) {
            TaskOperConnectModel connectModel = new TaskOperConnectModel();
            try {
                CopyUtils.copyProperties(model, connectModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(connectModel));
        } else if (2 == type) {
            TaskOperLMModel lmModel = new TaskOperLMModel();
            try {
                CopyUtils.copyProperties(model, lmModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(lmModel));

            //向物流系统发消息
            Integer planId = task.getShipPlanId();
            TaskShipPlan taskShipPlan = taskShipPlanService.getOne(new LambdaQueryWrapper<TaskShipPlan>().eq(TaskShipPlan::getId, planId).select(TaskShipPlan::getId, TaskShipPlan::getSerialNo));
            LocalDateTime kssj = null;
            LocalDateTime jssj = null;
            List<BusinessCheckModel> bcms = lmModel.getBusinessCheckModelList();
            if (CollectionUtils.isNotEmpty(bcms)) {
                //获取最小的起泵时间
                List<BusinessCheckModel> l2 = bcms.stream().filter(b -> null != b.getQb()).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(l2)) {
                    l2.sort(Comparator.comparing(BusinessCheckModel::getQb));
                    kssj = l2.get(0).getQb();
                }

                //获取最新的停泵时间
                List<BusinessCheckModel> l3 = bcms.stream().filter(b -> null != b.getTb()).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(l3)) {
                    l3.sort(Comparator.comparing(BusinessCheckModel::getTb));
                    Collections.reverse(l3);
                    jssj = l3.get(0).getTb();
                }
            }

            //向物流系统推送消息
            LocalDateTime finalKssj = kssj;
            LocalDateTime finalJssj = jssj;
            taskExecutor.submit(() -> {
                RestResult restResult = restUtils.updateShipLMStatus(taskShipPlan.getSerialNo(), lmModel.getKb(), finalKssj, finalJssj, lmModel.getLb());
                if (!"0".equals(restResult.getCode())) {
                    RestMsgFailLog restMsgFailLog = new RestMsgFailLog(restResult.getCode(), restResult.getMessage(), restResult.getSendInfo());
                    restMsgFailLogService.save(restMsgFailLog);
                }
            });
        } else if (4 == type) {
            TaskOperCCRModel ccrModel = new TaskOperCCRModel();
            try {
                CopyUtils.copyProperties(model, ccrModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            //ccr任务跟狗屎一样恶心的需求处理
            String detail = task.getOperDetail();
            if (StringUtils.isEmpty(detail))//第一次添加
            {
                List<TaskOperCCRModel> list = new ArrayList<>();
                list.add(ccrModel);
                task.setOperDetail(JSON.toJSONString(list));
            } else {
                int done = task.getCcrDone();
                int nowTime = done + 1;//本次操作的次数
                List<TaskOperCCRModel> list = JSON.parseArray(detail, TaskOperCCRModel.class);
                if (list.size() == nowTime)//说明临时保存过
                {
                    //那就把这条更新一下把
                    list.set(nowTime - 1, ccrModel);
                } else//说明当前是第一次保存这次，有点绕口，反正就是这个意思
                {
                    //那就把这次的对象放进list
                    list.add(ccrModel);
                }
                task.setOperDetail(JSON.toJSONString(list));
            }
        } else if (5 == type) {
            TaskOperDCQYModel dcqyModel = new TaskOperDCQYModel();
            try {
                CopyUtils.copyProperties(model, dcqyModel);
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(dcqyModel));
        } else if (3 == type || type > 5) {
            TaskOperOtherModel otherModel = new TaskOperOtherModel();
            try {
                CopyUtils.copyProperties(model, otherModel);
                otherModel.setUserMain(sysUserService.getOne(new LambdaQueryWrapper<SysUserEntity>().eq(SysUserEntity::getUserId, task.getUserMainId())).getName());
                String userAssist = task.getUserAssist();
                if (StringUtils.isNotEmpty(userAssist)) {
                    List<WorkUserModel> us = JSON.parseArray(userAssist, WorkUserModel.class);
                    List<String> ss = us.stream().map(workUserModel -> workUserModel.getName()).collect(Collectors.toList());
                    otherModel.setUserAssist(String.join(",", ss));
                }
            } catch (Exception e) {
                throw new RRException("类型与所传参数不匹配");
            }
            task.setOperDetail(JSON.toJSONString(otherModel));
        } else {
            throw new RRException("无效的类型");
        }
    }

}
